package pCloud.message;

import java.io.Serializable;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.HashMap;

import pCloud.exception.InvalidClientRequest;

/**
 * Request from the client, containing 1. The client's credentials: name, role.
 * 2. Requested resource: 2.1. Host 2.2. Database ID, Table ID, column ID 2.3.
 * Constrain: WHERE clause 3. Joining conditions: when there's more than one
 * requested resources, specifying columns whose values must be equal.
 */
public class ClientRequest implements Serializable {

	// This is used to index the client request at the proxy server.
	int requestId;
	ArrayList<RequestedResource> resources;
	HashMap<InetSocketAddress, String> joinColumns;

	boolean allNullJoiningColumn = false;

	public ClientRequest() {
		resources = new ArrayList<RequestedResource>();
		joinColumns = new HashMap<InetSocketAddress, String>();
		allNullJoiningColumn = false;
	}

	public void addRequestedResource(RequestedResource rr, String joinColumn)
			throws Exception {
		if (joinColumn != null && this.allNullJoiningColumn)
			throw new InvalidClientRequest("joining columns must be all null");
		if (joinColumn == null)
			this.allNullJoiningColumn = true;

		this.resources.add(rr);

		if (joinColumn != null) {
			this.joinColumns.put(rr.getHost(), joinColumn);
		}
	}

	public void setRequestId(int id) {
		this.requestId = id;
	}

	public ArrayList<RequestedResource> getResources() {
		return resources;
	}

	public HashMap<InetSocketAddress, String> getJoinColumns() {
		return joinColumns;
	}

	public int getRequestId() {
		return this.requestId;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + (allNullJoiningColumn ? 1231 : 1237);
		result = prime * result
				+ ((joinColumns == null) ? 0 : joinColumns.hashCode());
		result = prime * result + requestId;
		result = prime * result
				+ ((resources == null) ? 0 : resources.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		ClientRequest other = (ClientRequest) obj;
		if (allNullJoiningColumn != other.allNullJoiningColumn)
			return false;
		if (joinColumns == null) {
			if (other.joinColumns != null)
				return false;
		} else if (!joinColumns.equals(other.joinColumns))
			return false;
		if (requestId != other.requestId)
			return false;
		if (resources == null) {
			if (other.resources != null)
				return false;
		} else if (!resources.equals(other.resources))
			return false;
		return true;
	}
}
